package com.socket.controller;

import com.socket.utils.LogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

@RestController
@RequestMapping("/socketError")
public class SocketErrorController {

    private Timer timer;

    @Autowired
    private SimpMessagingTemplate template;

    @GetMapping("/protocolError")
    public String protocolError() {
        byte[] bytes = new byte[1024];
        template.convertAndSend("/topic/sub/errorTest", bytes);
        return "【1002】CLOSE_PROTOCOL_ERROR，由于协议错误而中断连接，此处是直接传入byte数组而导致的异常断开";
    }

    @GetMapping("/msgToSubErrorTest/{size}/{unit}")
    public String msgToSubErrorTest(@PathVariable("size") long size, @PathVariable("unit") String unit) {
        String testData = getTestData(size, unit);
        template.convertAndSend("/topic/sub/errorTest", testData);
        return "服务端向订阅号/topic/sub/errorTest发送消息";
    }

    /**
     * @param size
     * @param unit
     * @return
     * @description 经测试当单点向客户端发送消息时，消息大于sendBufferSizeLimit，socket不会断开，消息能发送成功
     * 当一段时间频繁向客户端推送消息时sendBufferSizeLimit设置为1MB，每100ms推送1MB大小消息，一段时间内消息推送正常，时间长了socket会断开，CloseStatus[code=4500, reason=null]
     * 每100ms推送2MB大小消息，2-5s socket会断开
     * 结论：引发【4500】断开的原因与消息消耗有关，消息被客户端迅速接收，不太占用缓存，消息太大且频繁发送，会在缓存池缓存，一旦超出缓存，socket就断开，错误码4500
     */
    @GetMapping("/sessionNotReliable/{size}/{unit}")
    public String sessionNotReliable(@PathVariable("size") long size, @PathVariable("unit") String unit) {
        String testData = getTestData(size, unit);
        LogUtil.info("开始推送消息");
        timer = new Timer(true);//是否是守护线程 isDaemon为true代表是，否代表不是
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                template.convertAndSend("/topic/sub/errorTest", testData);
            }
        }, new Date(), 100);
        return "【4500】SESSION_NOT_RELIABLE，传输的消息太大，超过向客户端发送消息的最大缓冲会引发此异常";
    }


    public String getTestData(long size, String unit) {
        StringBuilder sb = new StringBuilder();
        if ("B".equals(unit)) {
            size = size;
        } else if ("KB".equals(unit)) {
            size = size * 1024;
        } else if ("MB".equals(unit)) {
            size = size * 1024 * 1024;
        }
        for (int i = 0; i < size; i++) {
            sb.append("a");
        }
        return sb.toString();
    }

    @GetMapping("/stop")
    public String stop() {
        try {
            timer.cancel();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "关闭成功";
    }
}
